package handler

import (
	"errors"
	"fmt"
	"geekai/core"
	"geekai/core/types"
	logger2 "geekai/logger"
	"geekai/model"
	"geekai/utils"
	"github.com/gin-gonic/gin"
	"gorm.io/gorm"
	"strings"
)

var log = logger2.GetLogger()

type BaseHandler struct {
	App *core.AppServer
	DB  *gorm.DB
}

// GetTrim 获取URL后面拼接的string类型参数，并去除参数两边空格
func (h *BaseHandler) GetTrim(c *gin.Context, key string) string {
	return strings.TrimSpace(c.Query(key))
}

// GetInt 获取URL后面拼接的int类型参数，如果没有传递就设置默认值返回
func (h *BaseHandler) GetInt(c *gin.Context, key string, defaultValue int) int {
	return utils.IntValue(c.Query(key), defaultValue)
}

// GetFloat 获取URL后面拼接的float类型参数
func (h *BaseHandler) GetFloat(c *gin.Context, key string) float64 {
	return utils.FloatValue(c.Query(key))
}

// GetBool 获取URL后面拼接的bool类型参数
func (h *BaseHandler) GetBool(c *gin.Context, key string) bool {
	return utils.BoolValue(c.Query(key))
}

// PostInt 获取Form表单参数，如果参数不存在，就设置默认值返回
func (h *BaseHandler) PostInt(c *gin.Context, key string, defaultValue int) int {
	return utils.IntValue(c.PostForm(key), defaultValue)
}

// PostFloat 获取Form表单float类型参数
func (h *BaseHandler) PostFloat(c *gin.Context, key string) float64 {
	return utils.FloatValue(c.PostForm(key))
}

// PostBool 获取Form表单bool类型参数
func (h *BaseHandler) PostBool(c *gin.Context, key string) bool {
	return utils.BoolValue(c.PostForm(key))
}

// GetUserKey 获取用户登录成功存储到Redis中的Key
func (h *BaseHandler) GetUserKey(c *gin.Context) string {
	// 从Gin的上下文中获取用户ID，这个用户ID在用户授权校验中间件中设置的
	userId, ok := c.Get(types.LoginUserID)
	if !ok {
		return ""
	}
	return fmt.Sprintf("users/%v", userId)
}

// GetLoginUserId 获取当前请求接口的用户Id
func (h *BaseHandler) GetLoginUserId(c *gin.Context) uint {
	// 从Gin的上下文中获取用户ID，这个用户ID在用户授权校验中间件中设置的
	userId, ok := c.Get(types.LoginUserID)
	if !ok {
		return 0
	}
	return uint(utils.IntValue(utils.InterfaceToString(userId), 0))
}

// IsLogin 判断用户是否登录
func (h *BaseHandler) IsLogin(c *gin.Context) bool {
	// 调用上面获取用户ID的方法判断用户ID是否大于0，用户的ID不会小于等于0
	return h.GetLoginUserId(c) > 0
}

// GetLoginUser 获取登录用户信息
func (h *BaseHandler) GetLoginUser(c *gin.Context) (model.User, error) {
	// 获取用户缓存信息
	value, exists := c.Get(types.LoginUserCache)
	if exists {
		return value.(model.User), nil
	}
	userId, ok := c.Get(types.LoginUserID)
	if !ok {
		return model.User{}, errors.New("用户未登录")
	}
	var user model.User
	// 查询用户信息
	res := h.DB.Where("id", userId).First(&user)
	// 更新缓存
	if res.Error == nil {
		c.Set(types.LoginUserCache, user)
	}
	return user, res.Error
}
